package hc.j2me.util;

import hc.core.ConditionWatcher;
import hc.core.IWatcher;
import hc.core.RootConfig;
import hc.core.util.StringUtil;
import hc.j2me.Starter;
import hc.j2me.ui.RSConfig;

import java.io.ByteArrayInputStream;

import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import javax.microedition.media.control.ToneControl;
import javax.microedition.media.control.VolumeControl;

public class SoundUtil {
	private static boolean isSupportTone, isSupportAU;
	
	static {
		isSupportTone = isSupportTone();
		isSupportAU = isSupportAU();
	}
	/**
	 * @param note A note is given in the range of 0 to 127 inclusive, Defines the tone of the note as specified by the above formula.
	 * @param duration The duration of the tone in milli-seconds. Duration must be positive.
	 * @param volume Audio volume range from 0 to 100. 100 represents the maximum
	 */
	public static void playTone(int note, int duration, int volume){
		if(isSupportTone){
			final RSConfig config = Starter.config;
			if(config.isMute == false){
				try{
					if(config.toneStep == RSConfig.SOUND_FAIL){
						return;
					}else if(config.toneStep == RSConfig.SOUND_NO_TEST){
						//因为异常，所以先假定失败不支持，并保存
						config.toneStep = RSConfig.SOUND_FAIL;
						Starter.update(config);
					}
					Manager.playTone(note, duration, volume);
					if(config.toneStep == RSConfig.SOUND_FAIL){
						config.toneStep = RSConfig.SOUND_PASS;
						Starter.update(config);
					}
				}catch (Throwable e) {
					
				}
			}
		}
	}
	
//	private void test(){
//		String[] type = {"microedition.media.version", "supports.mixing", "audio.encodings", "streamable.contents"}; 
//		//{"audio/x-wav", "audio/basic", "audio/mpeg", "audio/midi", "audio/x-tone-seq"};
//		for (int i = 0; i < type.length; i++) {
//	//		String[] list = Manager.getSupportedProtocols(type[i]);
//	//		String out = "";
//			String out = System.getProperty(type[i]);
//	//		for (int j = 0; j < list.length; j++) {
//	//			out += " " + list[j];
//	//		}
//			LogManager.info(type[i] + ":");
//			LogManager.info(out);
//		}
//		try {
//			 byte tempo = 30; // set tempo to 120 bpm 
//			    byte d = 8;      // eighth-note 
//	
//			    byte C4 = ToneControl.C4;; 
//			    byte D4 = (byte)(C4 + 2); // a whole step 
//			    byte E4 = (byte)(C4 + 4); // a major third 
//			    byte G4 = (byte)(C4 + 7); // a fifth 
//			    byte rest = ToneControl.SILENCE; // rest 
//	
//			    byte[] mySequence = {
//			        ToneControl.VERSION, 1,   // version 1
//			        ToneControl.TEMPO, tempo, // set tempo
//			        ToneControl.BLOCK_START, 0,   // start define "A" section
//			        E4,d, D4,d, C4,d, E4,d,       // content of "A" section
//			        E4,d, E4,d, E4,d, rest,d,           
//			        ToneControl.BLOCK_END, 0,     // end define "A" section
//			        ToneControl.PLAY_BLOCK, 0,    // play "A" section
//			        D4,d, D4,d, D4,d, rest,d,     // play "B" section
//			        E4,d, G4,d, G4,d, rest,d,
//			        ToneControl.PLAY_BLOCK, 0,    // repeat "A" section
//			        D4,d, D4,d, E4,d, D4,d, C4,d  // play "C" section
//			    }; 
//			    
//		     Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
//		     p.realize();
//		     ToneControl tc = (ToneControl)p.getControl("ToneControl");
//		     tc.setSequence(mySequence);
//		     VolumeControl vc = (VolumeControl)p.getControl("VolumeControl");
//		     LogManager.info("isMuted : " + vc.isMuted());
//		     while(vc.getLevel() < 0){
//		    	 try{
//		    		 Thread.sleep(100);
//		    	 }catch (Exception e) {
//					
//				}
//		     }
//		     LogManager.info("level : " + vc.getLevel());
//		     vc.setLevel(80);
//		     p.prefetch();
//		     p.start();
//		     LogManager.info("start playing");
//		 } catch (IOException ioe) {
//			 LogManager.info(ioe.toString());
//		 } catch (MediaException me) {
//			 LogManager.info(me.toString());
//		 }
//		
//		Starter.soundOK();
//		Starter.soundOK();
//		
//		 InputStream is = this.getClass().getResourceAsStream("/hc/j2me/res/ship.au");
//		 
//		 if(is != null){
//			 LogManager.info("Get AU File");
//		 }
//			try{
//				Thread.sleep(3000);
//			}catch (Exception e) {
//				
//			}
//		 try {
//			 Player soundPlay = Manager.createPlayer(is,"audio/basic");
//			 soundPlay.realize();
//			 soundPlay.prefetch();
//			 soundPlay.start();
//		 } catch (IOException e) {
//			 LogManager.info(e.getMessage());
//			 e.printStackTrace();
//		 } catch (MediaException e) {
//			 LogManager.info(e.getMessage());
//			 e.printStackTrace();
//		 }
//	}

	//Sound Sample
//	public class ToneMIDlet extends MIDlet implements CommandListener {
//		  private final static String kSoundOfMusic = "Sound of Music";
//		  private final static String kQuandoMenVo = "Quando men vo";
//		  private final static String kTwinkle = "Twinkle number VII";
//		  private Display mDisplay;
//		  private List mMainScreen;
//		  public void startApp() {
//		    mDisplay = Display.getDisplay(this);
//		    if (mMainScreen == null) {
//		      mMainScreen = new List("AudioMIDlet", List.IMPLICIT);
//		      mMainScreen.append(kSoundOfMusic, null);
//		      mMainScreen.append(kQuandoMenVo, null);
//		      mMainScreen.append(kTwinkle, null);
//		      mMainScreen.addCommand(new Command("Exit", Command.EXIT, 0));
//		      mMainScreen.addCommand(new Command("Play", Command.SCREEN, 0));
//		      mMainScreen.setCommandListener(this);
//		    }
//
//		    mDisplay.setCurrent(mMainScreen);
//		  }
//
//		  public void pauseApp() {}
//
//		  public void destroyApp(boolean unconditional) {}
//		  public void commandAction(Command c, Displayable s) {
//		    if (c.getCommandType() == Command.EXIT) notifyDestroyed();
//		    else run();
//		  }
//
//		  public void run() {
//		    String selection = mMainScreen.getString(
//		        mMainScreen.getSelectedIndex());
//		    byte[] sequence = null;
//		    if (selection.equals(kSoundOfMusic)) {
//		      sequence = new byte[] {
//		        ToneControl.VERSION, 1,
//		        67, 16, // The
//		        69, 16, // hills
//		        67,  8, // are
//		        65,  8, // a -
//		        64, 48, // live
//		        62,  8, // with
//		        60,  8, // the
//		        59, 16, // sound
//		        57, 16, // of
//		        59, 32, // mu -
//		        59, 32  // sic
//		      };
//		    }
//		    else if (selection.equals(kQuandoMenVo)) {
//		      sequence = new byte[] {
//		        ToneControl.VERSION, 1,
//		        ToneControl.TEMPO, 22,
//		        ToneControl.RESOLUTION, 96,
//		        64, 48, ToneControl.SILENCE, 8, 52, 4, 56, 4, 59, 4, 64, 4,
//		        63, 48, ToneControl.SILENCE, 8, 52, 4, 56, 4, 59, 4, 63, 4,
//		        61, 72,
//		        ToneControl.SILENCE, 12, 61, 12,
//		            63, 12, 66, 2, 64, 10, 63, 12, 61, 12,
//		        64, 12, 57, 12, 57, 48,
//		        ToneControl.SILENCE, 12, 59, 12,
//		            61, 12, 64, 2, 63, 10, 61, 12, 59, 12,
//		        63, 12, 56, 12, 56, 48,
//		      };
//		    }
//		    else if (selection.equals(kTwinkle)) {
//		      sequence = new byte[] {
//		        ToneControl.VERSION, 1,
//		        ToneControl.TEMPO, 22,
//		        ToneControl.BLOCK_START, 0,
//		        60, 8,        62, 4, 64, 4, 65, 4, 67, 4, 69, 4, 71, 4,
//		        72, 4, 74, 4, 76, 4, 77, 4, 79, 4, 81, 4, 83, 4, 84, 4,
//		        83, 4, 81, 4, 80, 4, 81, 4, 86, 4, 84, 4, 83, 4, 81, 4,
//		        81, 4, 79, 4, 78, 4, 79, 4, 60, 4, 79, 4, 88, 4, 79, 4,
//		        57, 4, 77, 4, 88, 4, 77, 4, 59, 4, 77, 4, 86, 4, 77, 4,
//		        56, 4, 76, 4, 86, 4, 76, 4, 57, 4, 76, 4, 84, 4, 76, 4,
//		        53, 4, 74, 4, 84, 4, 74, 4, 55, 4, 74, 4, 83, 4, 74, 4,
//		        84, 16, ToneControl.SILENCE, 16,
//		        ToneControl.BLOCK_END, 0,
//		        ToneControl.BLOCK_START, 1,
//		        79, 4, 84, 4, 88, 4, 86, 4, 84, 4, 83, 4, 81, 4, 79, 4,
//		        77, 4, 76, 4, 74, 4, 72, 4, 71, 4, 69, 4, 67, 4, 65, 4,
//		        64, 8,        76, 8,        77, 8,        78, 8,
//		        79, 12,              76, 4, 74, 8, ToneControl.SILENCE, 8,
//		        ToneControl.BLOCK_END, 1,
//		        ToneControl.SET_VOLUME, 100, ToneControl.PLAY_BLOCK, 0,
//		        ToneControl.SET_VOLUME,  50, ToneControl.PLAY_BLOCK, 0,
//		        ToneControl.SET_VOLUME, 100, ToneControl.PLAY_BLOCK, 1,
//		        ToneControl.SET_VOLUME,  50, ToneControl.PLAY_BLOCK, 1,
//		        ToneControl.SET_VOLUME, 100, ToneControl.PLAY_BLOCK, 0,
//		      };
//		    }
//		    try {
//		      Player player = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
//		      player.realize();
//		      ToneControl tc = (ToneControl)player.getControl("ToneControl");
//		      tc.setSequence(sequence);
//		      player.start();
//		    }
//		    catch (Exception e) {
//		      Alert a = new Alert("Exception", e.toString(), null, null);
//		      a.setTimeout(Alert.FOREVER);
//		      mDisplay.setCurrent(a, mMainScreen);
//		    }
//		  }
//		}

	public static boolean isSupportAU() {
		String[] list = Manager.getSupportedProtocols("audio/basic");
		return (list != null && list.length >= 3);
	}

	public static boolean isSupportTone() {
		String[] list = Manager.getSupportedProtocols("audio/x-tone-seq");
		return (list != null && list.length >= 3);
	}
	
	public static void playMIDPStartTone(){
		final int volLevel = Integer.parseInt(RootConfig.getInstance().getProperty(
				RootConfig.p_MIDP_START_TONE_VOL_LEVEL));
		if(volLevel > 0 && Starter.config.isMute == false){
			String toneSeq = RootConfig.getInstance().getProperty(
					RootConfig.p_MIDP_START_TONE);
			String[] v = StringUtil.splitToArray(toneSeq, ",");
			final byte[] sequence = new byte[v.length];
			for (int i = 0; i < sequence.length; i++) {
				sequence[i] = (byte) Integer.parseInt(v[i]);
	//			L.V = L.O ? false : LogManager.log(String.valueOf(sequence[i]));
			}
			ConditionWatcher.addWatcher(new IWatcher() {
				public boolean watch() {
					try {
						Player player = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
						player.realize();
						VolumeControl vc = (VolumeControl)player.getControl("VolumeControl");
						vc.setLevel(volLevel);
						ToneControl tc = (ToneControl) player.getControl("ToneControl");
						tc.setSequence(sequence);
						player.prefetch();
						player.start();
					} catch (Throwable e) {
					}
					return true;
				}
				
				public void setPara(Object p) {
				}

				public void cancel() {
				}

				public boolean isNotCancelable() {
					return false;
				}
			});
		}
	}

	public static void playAU(ByteArrayInputStream ais) {
		if(isSupportAU){
			final RSConfig config = Starter.config;
			if(config.isMute == false){
				try{
					if(config.auStep == RSConfig.SOUND_FAIL){
						return;
					}else if(config.auStep == RSConfig.SOUND_NO_TEST){
						//因为异常，所以先假定失败不支持，并保存
						config.auStep = RSConfig.SOUND_FAIL;
						Starter.update(config);
					}
					Manager.createPlayer(ais, "audio/basic").start();
					if(config.auStep == RSConfig.SOUND_FAIL){
						config.auStep = RSConfig.SOUND_PASS;
						Starter.update(config);
					}
				}catch (Throwable e) {
					//e.printStackTrace();
				}
			}
		}
	}
}
